package com.ruoyi.oss.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.cache.CacheUtils;
import com.ruoyi.common.utils.cache.RedisUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.oss.constant.OssConstant;
import com.ruoyi.oss.domain.SysOssConfig;
import com.ruoyi.oss.event.domain.UpdateConfigCacheEvent;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.oss.mapper.SysOssConfigMapper;
import com.ruoyi.oss.service.ISysOssConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

@Slf4j
@Service
public class SysOssConfigServiceImpl extends ServiceImpl<SysOssConfigMapper, SysOssConfig> implements ISysOssConfigService {
    @Autowired
    RedisCache redisCache;
    @Autowired
    RedisUtils redisUtils;
    public SysOssConfigServiceImpl() {

    }

    public void init() {
        List<SysOssConfig> list = list();
        // 加载OSS初始化配置
        for (SysOssConfig config : list) {
            String configKey = config.getConfigKey();
            if ("0".equals(config.getStatus())) {
                redisCache.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey);
            }
            UpdateConfigCacheEvent event = new UpdateConfigCacheEvent(this, config);
            SpringUtil.publishEvent(event);
        }
        // 初始化OSS工厂
        OssFactory.init();
    }

    @Override
    public boolean save(SysOssConfig entity) {
        validEntityBeforeSave(entity);
        boolean flag = super.save(entity);
        if (flag) {
            UpdateConfigCacheEvent event = new UpdateConfigCacheEvent(this, entity);
            SpringUtil.publishEvent(event);
        }

        return flag;
    }

    @Override
    public boolean updateById(SysOssConfig entity) {
        validEntityBeforeSave(entity);
        boolean flag = super.updateById(entity);
        if (flag) {
            UpdateConfigCacheEvent event = new UpdateConfigCacheEvent(this, entity);
            SpringUtil.publishEvent(event);
        }
        return flag;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(SysOssConfig entity) {
        if (StringUtils.isNotEmpty(entity.getConfigKey())
                && UserConstants.NOT_UNIQUE == checkConfigKeyUnique(entity)) {
            throw new ServiceException("操作配置'" + entity.getConfigKey() + "'失败, 配置key已存在!");
        }
    }

    /**
     * 判断configKey是否唯一
     */
    private boolean checkConfigKeyUnique(SysOssConfig sysOssConfig) {
        long ossConfigId = ObjectUtil.isNull(sysOssConfig.getOssConfigId()) ? -1L : sysOssConfig.getOssConfigId();
        SysOssConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysOssConfig>()
                .select(SysOssConfig::getOssConfigId, SysOssConfig::getConfigKey)
                .eq(SysOssConfig::getConfigKey, sysOssConfig.getConfigKey()));
        if (ObjectUtil.isNotNull(info) && info.getOssConfigId() != ossConfigId) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public boolean removeByIds(Collection<?> list) {
        List<SysOssConfig> configList = CollectionUtil.newArrayList();
        list.forEach(configId -> {
            SysOssConfig config = SpringUtils.getAopProxy(this).getById((Serializable) configId);
            configList.add(config);
        });
        boolean flag = super.removeByIds(list);
        if (flag) {
            configList.forEach(sysOssConfig ->
                    CacheUtils.evict(CacheNames.SYS_OSS_CONFIG, sysOssConfig.getConfigKey()));
        }

        return super.removeByIds(list);
    }
}
